package com.yykj.common.handler;

import com.squareup.okhttp.internal.framed.ErrorCode;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.FeignClientException;
import com.yykj.common.exception.FeignServerException;
import com.yykj.common.exception.NormalException;
import com.yykj.common.util.JsonUtil;
import com.yykj.common.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.EOFException;
import java.util.List;

/**
 * Created by chendg on 2018/1/8 0008.
 */
@Slf4j
@ControllerAdvice
public class SystemExceptionHandler {


	/**
	 * 系统code = 200，提示错误
	 * @param e ErrorCodeException
	 * @return resultVo json string
	 */
	@ExceptionHandler(NormalException.class)
	@ResponseBody
	public ResultVO handlerErrorCodeException(NormalException e) {
		log.info("【业务】 NormalException {} ", e.getMsg());
		return ResultVO.error(e.getCode(), e.getMsg());
	}

    //入参validate异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultVO MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult result = e.getBindingResult();
        StringBuilder errorMsg = new StringBuilder();
        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            errorMsg.append(error.getDefaultMessage()).append("!");
        });
        ResultVO error = ResultVO.error(100,  errorMsg.toString());
        return error;
    }

	@ExceptionHandler(FeignServerException.class)
	@ResponseBody
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ResultVO handlerFeignServerException(FeignServerException e) {
		log.info("【业务】 FeignServerException {} ", e.getMsg());
		return ResultVO.error(e.getCode(), e.getMsg());
	}

	@ExceptionHandler(FeignClientException.class)
	@ResponseBody
	public ResultVO handlerFeignClientException(FeignClientException e) {
		log.info("【业务】 FeignClientException {} ", e.getMsg());
		return ResultVO.error(e.getCode(), e.getMsg());
	}


	/**
	 * 捕获 404 错误
	 * @param e NoHandlerFoundException
	 * @return resultVo json string
	 */
	@ExceptionHandler(NoHandlerFoundException.class)
	@ResponseBody
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public ResultVO handlerException(NoHandlerFoundException e) {
		return ResultVO.error(ResultEnums.SYSTEM_NOT_FOUND_ERROR);
	}

	@ExceptionHandler(MissingServletRequestParameterException.class)
	@ResponseBody
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public ResultVO handlerException(MissingServletRequestParameterException e) {
		return ResultVO.error(ResultEnums.PARAM_ERROR);
	}

	@ExceptionHandler(MethodArgumentTypeMismatchException.class)
	@ResponseBody
	public ResultVO handlerException(MethodArgumentTypeMismatchException e) {
		return ResultVO.error(ResultEnums.PARAM_ERROR);
	}

	/**
	 * 捕获 500 错误
	 * @param e Exception
	 * @return resultVo json string
	 */
	@ExceptionHandler(Exception.class)
	@ResponseBody
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public ResultVO handlerException(Exception e) {
		log.error("【系统错误】{}", e.getMessage());
		e.printStackTrace();
		return ResultVO.error(ResultEnums.SYSTEM_ERROR.getCode(), e.getMessage());
	}

	@ExceptionHandler(EOFException.class)
	public void handlerEOFException(EOFException e) {
		log.error("【WEB SOCKET】{}", e.getMessage());
	}

}
